#include "WindowDebug.h"

WindowDebug::WindowDebug(GLFWwindow* window) :
m_window(window)
{
}

bool WindowDebug::restart_gl_log()
{
	time_t now;
	char* date;
	FILE* file = fopen(GL_LOG_FILE, "w");

	if (!file)
	{
		fprintf(stderr, "ERROR: could not open GL_LOG_FILE log file %s for writing\n", GL_LOG_FILE);
		return false;
	}
	now = time(NULL);	// saves time
	date = ctime(&now);	// saves date
	fprintf(file, "GL_LOG_FILE log. local time %s\n", date);	// prints the date and time at the top
	fprintf(file, "build version: %s %s\n\n", __DATE__, __TIME__);
	fclose(file);	// close file
	return true;
}

// add a message to the log file (arguments work the same way as printf()
bool WindowDebug::gl_log(const char* message, ...)
{
	va_list argptr;
	FILE* file = fopen(GL_LOG_FILE, "a");	// open file in append mode
	if (!file)
	{
		fprintf(stderr, "ERROR: could not open GL_LOG_FILE %s file for appending\n", GL_LOG_FILE);
		return false;
	}
	va_start(argptr, message);
	vfprintf(file, message, argptr);
	va_end(argptr);
	fclose(file);
	return true;
}

// same as gl_log except also prints to stderr
bool WindowDebug::gl_log_err(const char* message, ...)
{
	va_list argptr;
	FILE* file = fopen(GL_LOG_FILE, "a");	// open file in append mode
	if (!file)
	{
		fprintf(stderr, "ERROR: could not open GL_LOG_FILE %s file for appending\n", GL_LOG_FILE);
		return false;
	}
	va_start(argptr, message);
	vfprintf(file, message, argptr);
	va_end(argptr);
	va_start(argptr, message);
	vfprintf(stderr, message, argptr);
	va_end(argptr);
	fclose(file);
	return true;
}

// we can use a function like this to print some GL capabilities of our adapter to
// the log file. handy if we want to debug problems on other people's computers
void WindowDebug::log_gl_params()
{
	int i;
	int v[2];
	unsigned char s = 0;
	GLenum params[] =
	{
		GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
		GL_MAX_CUBE_MAP_TEXTURE_SIZE,
		GL_MAX_DRAW_BUFFERS,
		GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
		GL_MAX_TEXTURE_IMAGE_UNITS,
		GL_MAX_TEXTURE_SIZE,
		GL_MAX_VARYING_FLOATS,
		GL_MAX_VERTEX_ATTRIBS,
		GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
		GL_MAX_VERTEX_UNIFORM_COMPONENTS,
		GL_MAX_VIEWPORT_DIMS,
		GL_STEREO,
	};
	const char* names[] =
	{
		"GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS",
		"GL_MAX_CUBE_MAP_TEXTURE_SIZE",
		"GL_MAX_DRAW_BUFFERS",
		"GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
		"GL_MAX_TEXTURE_IMAGE_UNITS",
		"GL_MAX_TEXTURE_SIZE",
		"GL_MAX_VARYING_FLOATS",
		"GL_MAX_VERTEX_ATTRIBS",
		"GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS",
		"GL_MAX_VERTEX_UNIFORM_COMPONENTS",
		"GL_MAX_VIEWPORT_DIMS",
		"GL_STEREO",
	};
	WindowDebug::gl_log("GL Context Params: \n");
	// integers - only works if the ordes is 0 - 10 integer return types
	for (i = 0; i < 10; i++)
	{
		int v = 0;
		glGetIntegerv(params[i], &v);
		WindowDebug::gl_log("%s %i\n", names[i], v);
	}
	// others
	v[0] = v[1] = 0;
	glGetIntegerv(params[10], v);
	WindowDebug::gl_log("%s %i %i\n", names[10], v[0], v[1]);
	glGetBooleanv(params[11], &s);
	WindowDebug::gl_log("%s %i\n", names[11], (unsigned int)s);
	WindowDebug::gl_log("-----------------------------\n");
}

// we will use this function to update the window title bar with a frame rate
void WindowDebug::_update_fps_counter()
{
	double current_seconds;
	double elapsed_seconds;

	current_seconds = glfwGetTime();
	elapsed_seconds = current_seconds - previous_seconds;
	if (elapsed_seconds > 0.25)
	{
		previous_seconds = current_seconds;
		char tmp[128];
		double fps = (double)frame_count / elapsed_seconds;
		sprintf(tmp, "opengl @ fps: %.2f", fps);
		glfwSetWindowTitle(m_window, tmp);
		frame_count = 0;
	}
	frame_count++;
}